import type { PageQueryDTO, PageQueryVO } from "@/api/type/baseType";
import setting from "@/setting";
import { onBeforeMount, ref } from "vue";

/**
 * 查询
 * @param queryFunction 执行查询的方法
 * @param loadBeforeMountParam 在组件挂载前执行一次查询的参数，不传递则不执行挂载前执行
 */
export const useQuery = <PARAM, RESULT>(
    queryFunction: (param: PARAM) => Promise<RESULT>,
    loadBeforeMountParam?: PARAM
) => {
    // 查询结果
    const resultData = ref<RESULT>({} as RESULT)
    // 查询状态
    const isLoading = ref(false)

    // 封装查询方法
    const handleQuery = async (param: PARAM) => {
        isLoading.value = true
        try {
            resultData.value = await queryFunction(param)
        } finally {
            isLoading.value = false
        }
    }

    // 若loadBeforeMountParam存在，则在挂载前执行一次查询
    if (loadBeforeMountParam) {
        onBeforeMount(() => {
            handleQuery(loadBeforeMountParam)
        })
    }

    return {
        handleQuery,
        resultData,
        isLoading
    }
}

/**
 * 分页查询
 * @param pageQueryFunction 执行分页查询的方法
 * @param loadBeforeMount 是否在组件挂载前执行一次查询的参数，缺省则为true
 * @returns 
 */
export const usePageQuery = <PARAM, RESULT>(
    pageQueryFunction: (params: PageQueryDTO<PARAM>) => Promise<PageQueryVO<RESULT>>,
    loadBeforeMount: boolean = true
) => {
    const result = useQuery<PageQueryDTO<PARAM>, PageQueryVO<RESULT>>(
        pageQueryFunction,
        loadBeforeMount ? setting.getDefaultPageQueryParam<PARAM>() : undefined
    )

    // 查询时的其它附加参数
    const otherQueryParam = ref<PARAM>()

    // 重新封装handleQuery，当有参数时使用参数，无参数时若有页码状态则用当前的页码状态，若以上两个都没用则用默认值
    const handleQuery = (param?: PageQueryDTO<PARAM>) => {
        let pageNum = param?.pageNum ?? result.resultData.value.current ?? null
        let pageSize = param?.pageSize ?? result.resultData.value.size ?? null
        if (pageNum === null || pageSize === null) {
            const defaultSetting = setting.getDefaultPageQueryParam<PARAM>()
            if (pageNum === null) {
                pageNum = defaultSetting.pageNum
            }
            if (pageSize === null) {
                pageSize = defaultSetting.pageSize
            }
        }
        return result.handleQuery({
            pageNum,
            pageSize,
            param: param?.param ?? otherQueryParam.value
        }
        )
    }

    // 查询附加参数改变时执行
    const handleParamChange = (otherParam: PARAM) => {
        otherQueryParam.value = otherParam
    }

    return {
        /**
         * 执行查询
         */
        handleQuery,
        /**
         * 查询附加参数改变时通过这个方法修改附加参数
         */
        handleParamChange,
        /**
         * 查询结果
         */
        resultData: result.resultData,
        /**
         * 是否正在执行查询
         */
        isLoading: result.isLoading
    }
}